var fs = require('fs'); // get the fs module
var http = require('http');
var url = require('url');
var util = require('util');
var array = new Array().push(1,2);
var fileMappingConfig = {
    'apps/malldetail/': '/home/looop/workspace/malldetail/assets/'
};
http.createServer(function(req, res){
    var request = url.parse(req.url, true);
    var reqPath = request.pathname;
    var list = parseRequest(request);
    if(list.length == 0){
    	returen404(res);
    }
    var dispatchResult = dispatchRequest(list, fileMappingConfig);
    //console.log(dispatchResult);
    var responseCountdownLatch = new ResponseCountDownLatch(list.length, res, dispatchResult['list']);
    for(var i=0; i < dispatchResult['file'].length; i++){
    	readFromFile(dispatchResult['file'][i], res, responseCountdownLatch);
    }
    for(var i=0; i < dispatchResult['net'].length; i++){
    	readFromServer(dispatchResult['net'][i], res, responseCountdownLatch);
    }
    
}).listen(1337, "127.0.0.1");

console.log('Server running at http://127.0.0.1:1337/');

function parseRequest(request){
	var requestPathList = new Array();
	if(request.pathname != '/'){
		requestPathList.push(request.pathname);
	}else{
		for(var param in request.query){
			if(param.indexOf('?') == 0){
				param  = param.substring(1);
				var strList = param.split(',');
				for(var i=0; i < strList.length; i++){
					requestPathList.push(strList[i].split('?')[0]);
				}
			}
		}
	}
	return requestPathList;
}

function dispatchRequest(list, fileMappingConfig){
	var result = {'file':[], 'net':[], 'list' : []};
	for(var i=0; i < list.length; i++){
		var isFileMapping = false;
		var reqPath = list[i];
		for (var patten in fileMappingConfig) {
			//console.log(reqPath);
	        if (reqPath.indexOf(patten) == 0) {
	            var filepath = fileMappingConfig[patten] + reqPath.substring(patten.length);
	            result['file'].push(filepath);
	            isFileMapping = true;
	            result['list'].push(filepath);
	            break;
	        }
    	}
    	if(!isFileMapping){
    		result['net'].push(reqPath)
    		result['list'].push(reqPath);
    	}
	}
	return result;
}

function readFromFile(filepath, res, countdownLatch){
    fs.exists(filepath, function(exists){
        if (exists) {
            res.writeHead(200, {
                'Content-Type': 'text/plain'
            });
            var readstream = fs.createReadStream(filepath);
            var result = '';
            readstream.on('data', function(data){
            	result += data.toString();
            });
            readstream.on('end', function(){
            	countdownLatch.countdown(filepath, result);
            });
        }
        else {
            //console.log(filepath + ' file not exists, exists:' + exists);
            res.writeHead(404, {
                'Content-Type': 'text/plain'
            });
			countdownLatch.countdown();
        }
    })
}

function readFromServer(reqPath, res, countdownLatch){
    var options = {
        host: 'a.tbcdn.cn',
        port: 80,
        path: '/' + reqPath,
        method: 'GET'
    };
    var response = res;
    var req = http.request(options, function(res){
        //        console.log('STATUS: ' + res.statusCode);
        //        console.log('HEADERS: ' + JSON.stringify(res.headers));
        var result = '';
        //console.log(util.inspect(options));
        res.setEncoding('utf8');
        if(res.statusCode == 200){
	        res.on('data', function(chunk){
	        	result += chunk;
	        });
	        res.on('end', function(){
	        	countdownLatch.countdown(reqPath, result);
	        });
        }else{
        	countdownLatch.countdown(reqPath, result);
        }
    });
    req.on('error', function(e){
        console.log('problem with request: ' + util.inspect(e) + e.message + ' ' + reqPath);
        countdownLatch.countdown();
    });
    req.end();
}

function ResponseCountDownLatch(count, res, pathList){
    this.count = count;
    this.res = res;
    this.result = new Array();
    this.pathList = pathList;
    this.countdown = function(path, data){
    	var result = this.result;
    	if(typeof path != 'undefined' && typeof data != 'undefined'){
    		result[path] = data;
	    	
    	}else{
    		//console.log('**************' + typeof path);
    	}
        count--;
        if (count == 0) {
        	var size = 0;
        	for(var i=0; i < pathList.length; i++){
				if(typeof result[pathList[i]] != 'undefined' && result[pathList[i]] != null){
					res.write(result[pathList[i]]);
					size++;
				}else{
					//console.log(typeof result[pathList[i]]);
					//console.log(result[pathList[i]]);
				}
        	}
        	//console.log(size);
            res.end();
        }
    }
}

function returen404(res){
	res.writeHead(404, {
    	'Content-Type': 'text/plain'
    });
	res.end();
}

